import { Context } from 'koa';
import { getManager, IsNull} from 'typeorm';
  
import { Order } from '../entity/order';
import { Client } from '../entity/client';
import { Delivery } from '../entity/delivery';

export default class OrderController {

  /**
   * 返回所有的Order
   * @param ctx 
   */
  public static async listOrders(ctx: Context) {
    const orderRepository = getManager().getRepository(Order);
    const orders = await orderRepository.query(`SELECT * FROM \`order\` ORDER BY id DESC`);
    
    if (orders) {
      ctx.status = 200;
      ctx.body = orders;
    } else {
      ctx.status = 500;
    }
    
  }

  /**
   * 通过clientId，返回该用户Id下的所有未送货的Order
   * @param ctx 
   */
  public static async listOrdersByClientId(ctx: Context) {
    const orderRepository = getManager().getRepository(Order);
    const clientId = ctx.params.clientId;
    const orders = await orderRepository
      .createQueryBuilder("order")
      .where("order.clientId = :clientId", { clientId })
      .andWhere("order.deliveryId IS NULL")
      .getMany();
    
    if (orders) {
      ctx.status = 200;
      ctx.body = orders;
    } else {
      ctx.status = 500;
    }
    
  }

    /**
   * 新增Order，Post方法
   * @param ctx 上下文
   */
  public static async appendOrder(ctx: Context) {
    const orderRepository = getManager().getRepository(Order);
    const clientRepository = getManager().getRepository(Client);

    const clientId: string = ctx.params.clientId;
    // 先找到对应的Client
    const client = await clientRepository.findOne(clientId);

    if (client == undefined) {
      ctx.status = 503;
      ctx.body = {
        message: 'client not found'
      };
      return;
    }

    const data = ctx.request.body.orders;
    
    // 创建实体Array
    const newOrders = data.map((value: Order) => {
      const newOrder = new Order();

      newOrder.po = value.po;
      newOrder.goodsNumber = value.goodsNumber;
      newOrder.goodsType = value.goodsType;
      newOrder.quality = value.quality;
      newOrder.size = value.size;
      newOrder.quantity = value.quantity;
      newOrder.price = value.price;
      newOrder.amount = value.amount;
      newOrder.remark = value.remark;
      newOrder.client = client;

      return newOrder;
    });

  
    // 保存到数据库
    const orders = await orderRepository.save(newOrders);
    
    if (orders) {
      ctx.status = 201;
      ctx.body = orders.map((value: Order) => {
        return value.id;
      });
    } else {
      ctx.status = 500;
    }
  }

  /**
   * 根据订单ID，查找订单，Get方法
   * @param ctx 上下文
   */
  public static async checkOrder(ctx: Context) {
    const orderRepository = getManager().getRepository(Order);
    
    // 要查找的对象
    const id: string = ctx.params.id;

    const order = (await orderRepository.query(`SELECT * FROM \`order\` WHERE id = ${id}`))[0];
    
    if (order) {
      ctx.status = 200;
      ctx.body = order;
    } else {
      ctx.status = 500;
    }
  }

  /**
   * 更新未送货的订单信息
   * @param ctx 上下文
   */
  public static async updateOrder(ctx: Context) {
    const orderRepository = getManager().getRepository(Order);
    
    // 要修改的订单id
    const id: string = ctx.params.id;

    const deliveryId = (await orderRepository.query(`SELECT deliveryId FROM \`order\` WHERE id = ${id}`))[0].deliveryId;

    // 如果deliveryId不是null，则不允许修改
    if (!(deliveryId == null)) {
      ctx.status = 409;
      ctx.body = {
        message: 'Order has been delivered'
      };
      return;
    }

    // 更新
    await orderRepository.update(id, ctx.request.body);
    // 获得更新之后的对象
    const updatedOrder = await orderRepository.findOne(id);
    
    if (updatedOrder) {
      ctx.status = 200;
      ctx.body = updatedOrder;
    } else {
      ctx.status = 500;
    }
  }

  /**
   * 更新已送货的订单信息
   * @param ctx 上下文
   */
  public static async updateOrderDelivered(ctx: Context) {
    const orderRepository = getManager().getRepository(Order);
    
    // 要修改的订单id
    const id: string = ctx.params.id;

    const deliveryId = (await orderRepository.query(`SELECT deliveryId FROM \`order\` WHERE id = ${id}`))[0].deliveryId;

    // 如果deliveryId不是null，则不允许修改
    if ((deliveryId == null)) {
      ctx.status = 409;
      ctx.body = {
        message: 'Order has not been delivered'
      };
      return;
    }

    // 如果修改了金额
    if ('amount' in ctx.request.body) {
      // 要修改的order
      const order: Order = (await orderRepository.query(`SELECT * FROM \`order\` WHERE id = ${id}`))[0];
      const amountPre: number = order.amount;
      const amountAfter: number = ctx.request.body.amount;
      if (amountPre !== amountAfter) {
        const amountMargin: number = amountAfter - amountPre;
        const deliveryRepository = getManager().getRepository(Delivery);
        // 更新该订单所在的送货单的金额
        const delivery = await deliveryRepository.createQueryBuilder("delivery")
          .where("delivery.id = :id", {id: deliveryId})
          .getOne();

        if (delivery) {
          const updatedTotalAmount:number = delivery.totalAmount + amountMargin;
          await deliveryRepository.update(+deliveryId, {
            totalAmount: updatedTotalAmount
          });
          const updatedDelivery = await deliveryRepository.findOne(deliveryId);
        }
        else {
          ctx.status = 500;
          ctx.body = 'cannot find targetDelivery of this order';
        }
        
      }
    }

    // 更新
    await orderRepository.update(id, ctx.request.body);
 
    // 获得更新之后的对象
    const updatedOrder = await orderRepository.findOne(id);
    
    if (updatedOrder) {
      ctx.status = 200;
      ctx.body = updatedOrder;
    } else {
      ctx.status = 500;
    }
  }

  /**
   * 删除订单，根据订单的id。但如果这份订单已经跟deliveryId绑定，则会报错。
   * @param ctx 上下文
   */
  public static async deleteOrder(ctx: Context) {
    const orderRepository = getManager().getRepository(Order);

    // 要删除的订单
    const id = ctx.params.id;
    const order = await orderRepository.createQueryBuilder("order")
      .where("order.id = :id", {id})
      .getRawOne();

    // 如果找不到这个order
    if (order == undefined) {
      ctx.status = 500;
      ctx.body = {
        message: 'order not found'
      };
      return;
    }
    // 如果该订单已经被delivery选定
    if (!(order.order_deliveryId == null)) {
      ctx.status = 500;
      ctx.body = {
        message: 'Order has been delivered'
      };
      return;
    }

    // 删除对应订单
    await orderRepository.delete(id);
  
    ctx.status = 204;
    ctx.body = `Order deleted ${id}`;
  }
}
